/*
 * @(#)AbstractResult.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.result;

import java.util.Map;
import java.util.Properties;
import java.util.Scanner;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nhncorp.lucy.common.config.model.ApplicationInfo;
import com.nhncorp.lucy.web.helper.ServletHelper;

import com.nhncorp.usf.core.config.runtime.ResultPageInfo;
import com.nhncorp.usf.core.util.StringUtil;
import com.nhncorp.usf.core.xwork.UsfActionInvocation;

import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.Result;

/**
 * 인코딩과 content 타입 설정을 포함한 {@link Result} 추상 클래스.
 *
 * @author Web Platform Development Team.
 */
public abstract class AbstractResult implements Result {
	private static final long serialVersionUID = 3988853951445999643L;

	protected Log log = LogFactory.getLog(AbstractResult.class);

    /**
     * 페이지 인코딩.
     */
    protected String encoding = "utf-8";

    /**
     * template의 contentType( text/html 또는 text/xml)
     */
    protected String contentType = "text/html";

    /**
     * 응답으로 보낼 params {@link Properties}.
     */
    private Properties requestParams;

    /**
     * 페이지 인코딩 설정.
     * 
     * @param encoding the encoding value
     */
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * 페이지 인코딩 반환.
     * {@link ResultPageInfo} 에 의해 정의된 encoding 이 존재할 경우 그것을 반환하고
     * 없는 경우 {@link ApplicationInfo#getPageEncoding()} 을 반환한다.
     * 
     * @return the encoding value
     */
    public String getPageEncoding() {
        return encoding == null ? ApplicationInfo.getPageEncoding() : encoding;
    }

    /**
     * template의 contentType( text/html 또는 text/xml)
     * 
     * @param contentType the content type
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * requestParams 설정
     * 
     * @param requestParams the Properties
     */
    public void setRequestParams(Properties requestParams) {
        this.requestParams = requestParams;
    }

    /**
     * requestParams 반환
     * 
     * @return the request parameter properties
     */
    public Properties getRequestParams() {
        return this.requestParams;
    }

    /**
     * 사용자 정의 header 설정
     * 
     * @param resultPageInfo the result page information
     */
    protected void setHeader(ResultPageInfo resultPageInfo) {
        Properties property = resultPageInfo.getProperties();

        if (property == null) {
            return;
        }

        String header = property.getProperty("header");

        if (StringUtil.isEmpty(header)) {
            return;
        }

        HttpServletResponse response = ServletHelper.getResponse();
        Scanner scanner = new Scanner(header);
        scanner.useDelimiter("\n");

        while (scanner.hasNext()) {
            String line = scanner.next();

            if (line == null || line.indexOf(":") < 0) {
                continue;
            } else {
                String[] headerKeyValue = line.split("\\:");

                if (headerKeyValue.length == 2 && headerKeyValue[0] != null && headerKeyValue[1] != null) {
                    response.setHeader(headerKeyValue[0].trim(), headerKeyValue[1].trim());

                    if (log.isDebugEnabled()) {
                        log.debug("User Defined Header [key]:" + headerKeyValue[0].trim() + " [value]:"
                                + headerKeyValue[1].trim());
                    }

                }

            }

        }
    }

    /**
     *
     * @param actionInvocation the ActionInvocation
     * @throws Exception the Exception
     */
    public void execute(ActionInvocation actionInvocation) throws Exception {
        if (!(actionInvocation instanceof UsfActionInvocation)) {
            throw new IllegalArgumentException();
        }

        UsfActionInvocation usfActionInvocation = (UsfActionInvocation)actionInvocation;
        setHeader(usfActionInvocation.getResultPageInfo());
        execute(usfActionInvocation.getResultPageInfo(), usfActionInvocation.getDataMap());
    }

    /**
     * Execute.
     *
     * @param resultPageInfo the result page info
     * @param dataMap        the data map
     * @throws Exception the exception
     */
    public abstract void execute(ResultPageInfo resultPageInfo, Map<String, Object> dataMap) throws Exception;
}
